package com.hh.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.hh.common.config.RabbitMqConfig;
import com.hh.common.constants.Constants;
import com.hh.common.constants.PayConstants;
import com.hh.common.constants.SysConfigConstants;
import com.hh.common.constants.TaskConstants;
import com.hh.common.exception.HhException;
import com.hh.common.model.cat.StoreCart;
import com.hh.common.model.order.StoreOrder;
import com.hh.common.model.order.StoreOrderInfo;
import com.hh.common.model.order.StoreOrderStatus;
import com.hh.common.model.product.StoreProduct;
import com.hh.common.model.product.StoreProductAttrValue;
import com.hh.common.model.user.User;
import com.hh.common.model.user.UserAddress;
import com.hh.common.page.CommonPage;
import com.hh.common.request.*;
import com.hh.common.response.*;
import com.hh.common.utils.DateUtil;
import com.hh.common.utils.HhUtil;
import com.hh.common.utils.MerUtils;
import com.hh.common.utils.RedisUtil;
import com.hh.common.vo.MyRecord;
import com.hh.common.vo.OrderInfoDetailVo;
import com.hh.common.vo.OrderInfoVo;
import com.hh.common.vo.StoreOrderInfoVo;
import com.hh.common.vo.user.UserInfoVo;
import com.hh.service.dao.StoreOrderDao;
import com.hh.service.dao.StoreOrderInfoDao;
import com.hh.service.dao.StoreProductAttrValueDao;
import com.hh.service.dao.StoreProductDao;
import com.hh.service.delete.OrderUtils;
import com.hh.service.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class NewOrderServiceImpl implements NewOrderService {

    @Resource
    private StoreOrderDao dao;

    @Resource
    private StoreOrderInfoDao storeOrderInfoDao;

    @Resource
    private StoreProductDao storeProductDao;

    @Resource
    private StoreProductAttrValueDao storeProductAttrValueDao;

    @Autowired
    private UserService userService;

    @Autowired
    private StoreCartService storeCartService;

    @Autowired
    private StoreProductService storeProductService;

    @Autowired
    private UserAddressService userAddressService;

    @Autowired
    private StoreProductAttrValueService attrValueService;


    @Autowired
    private StoreOrderInfoService storeOrderInfoService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private OrderUtils orderUtils;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private NewOrderService newOrderService;

    @Autowired
    private StoreOrderStatusService storeOrderStatusService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 订单预下单
     * @param request
     * @return
     */
    @Override
    public MyRecord preOrder(NewPreOrderRequest request) {
        if (CollUtil.isEmpty(request.getOrderDetails())) {
            throw new HhException("预下单订单详情列表不能为空");
        }
        User user = userService.getInfoException();
        // 校验预下单商品信息
        OrderInfoVo orderInfoVo = validatePreOrderRequest(request, user);
        // 商品总计金额
//        if (orderInfoVo.getOrderDetailList().get(0).getProductType().equals(Constants.PRODUCT_TYPE_NORMAL)) {
//            // 普通商品
//            totalPrice = orderInfoVo.getOrderDetailList().stream().map(e -> e.getVipPrice().multiply(new BigDecimal(e.getPayNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
//        } else {
//            totalPrice = orderInfoVo.getOrderDetailList().stream().map(e -> e.getPrice().multiply(new BigDecimal(e.getPayNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
//        }

        BigDecimal totalPrice = orderInfoVo.getOrderDetailList().stream().map(e -> e.getPrice().multiply(new BigDecimal(e.getPayNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);

        orderInfoVo.setProTotalFee(totalPrice);
        // 购买商品总数量
        int orderProNum = orderInfoVo.getOrderDetailList().stream().mapToInt(OrderInfoDetailVo::getPayNum).sum();
        orderInfoVo.setOrderProNum(orderProNum);
        // 获取默认地址
        UserAddress userAddress = userAddressService.getDefaultByUid(user.getUid());
        if (ObjectUtil.isNotNull(userAddress)) {
            // 计算运费
            getFreightFee(orderInfoVo);
            orderInfoVo.setAddressId(userAddress.getId());
            orderInfoVo.setRealName(userAddress.getRealName());
            orderInfoVo.setPhone(userAddress.getPhone());
            orderInfoVo.setProvince(userAddress.getProvince());
            orderInfoVo.setCity(userAddress.getCity());
            orderInfoVo.setDistrict(userAddress.getDistrict());
            orderInfoVo.setDetail(userAddress.getDetail());
        } else {
            orderInfoVo.setFreightFee(BigDecimal.ZERO);
        }
        // 实际支付金额
        orderInfoVo.setPayFee(orderInfoVo.getProTotalFee().add(orderInfoVo.getFreightFee()));
        orderInfoVo.setUserIntegral(user.getIntegral());
        orderInfoVo.setUserBalance(user.getNowMoney());
        // 缓存订单
        String key = user.getUid() + DateUtil.getNowTime().toString()+ HhUtil.getUuid();
        redisUtil.set("user_order:" + key, JSONObject.toJSONString(orderInfoVo), Constants.ORDER_CASH_CONFIRM, TimeUnit.MINUTES);
        MyRecord record = new MyRecord();
        record.set("preOrderNo", key);
        return record;
    }

    @Override
    public StoreOrder getByOderId(String orderId) {
        LambdaQueryWrapper<StoreOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(StoreOrder::getOrderId, orderId);
        return dao.selectOne(lqw);
    }

    @Override
    public PreOrderResponse loadPreOrder(String preOrderNo) {
        UserInfoVo simpleInfoException = userService.getSimpleInfoException();
        String merId = simpleInfoException.getMerId();
        boolean isMer = MerUtils.isMer(merId);

        // 通过缓存获取预下单对象
        String key = "user_order:" + preOrderNo;
        boolean exists = redisUtil.exists(key);

        if (!exists) {
            throw new HhException("预下单订单不存在");
        }
        String orderVoString = redisUtil.get(key).toString();
        OrderInfoVo orderInfoVo = JSONObject.parseObject(orderVoString, OrderInfoVo.class);
        PreOrderResponse preOrderResponse = new PreOrderResponse();
        preOrderResponse.setOrderInfoVo(orderInfoVo);
        String payWeixinOpen = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_PAY_WEIXIN_OPEN,isMer,merId);
        if (orderInfoVo.getIsVideo()) {
            // 关闭余额支付和到店自提
            preOrderResponse.setYuePayStatus("0");
            preOrderResponse.setPayWeixinOpen(payWeixinOpen);
            preOrderResponse.setStoreSelfMention("false");
            preOrderResponse.setAliPayStatus("0");
            return preOrderResponse;
        }
        String yuePayStatus = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_YUE_PAY_STATUS,isMer,merId);// 1开启 2关闭
        String storeSelfMention = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_KEY_STORE_SELF_MENTION,isMer,merId);
        String aliPayStatus = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_ALI_PAY_STATUS,isMer,merId);// 1开启
        preOrderResponse.setYuePayStatus(yuePayStatus);
        preOrderResponse.setPayWeixinOpen(payWeixinOpen);
        preOrderResponse.setStoreSelfMention(storeSelfMention);
        preOrderResponse.setAliPayStatus(aliPayStatus);
        return preOrderResponse;
    }

    @Override
    public MyRecord createOrder(CreateOrderRequest request) {
        UserInfoVo userInfoVo = userService.getSimpleInfoException();
        String merId = userInfoVo.getMerId();
        boolean isMer = MerUtils.isMer(merId);

        // 通过缓存获取预下单对象
        String key = "user_order:" + request.getPreOrderNo();
        boolean exists = redisUtil.exists(key);
        if (!exists) {
            throw new HhException("预下单订单不存在");
        }
        String orderVoString = redisUtil.get(key).toString();
        OrderInfoVo orderInfoVo = JSONObject.parseObject(orderVoString, OrderInfoVo.class);

        // 检测支付方式
        if (!orderUtils.checkPayType(request.getPayType(),isMer,merId)) {
            throw new HhException("暂不支持该支付方式，请刷新页面或者联系管理员");
        }

        if (request.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) {
            // 检测支付渠道
            if (StrUtil.isBlank(request.getPayChannel())) {
                throw new HhException("支付渠道不能为空!");
            }
            if (!OrderUtils.checkPayChannel(request.getPayChannel())) {
                throw new HhException("支付渠道不存在!");
            }
        }

        // 校验商品库存
        List<MyRecord> skuRecordList = validateProductStock(orderInfoVo, userInfoVo);

        // 校验收货信息
        String verifyCode = "";
        String userAddressStr = "";
        if (request.getShippingType() == 1) { // 快递配送
            if (request.getAddressId() <= 0) {
                throw new HhException("请选择收货地址");
            }
            UserAddress userAddress = userAddressService.getById(request.getAddressId());
            if (ObjectUtil.isNull(userAddress) || userAddress.getIsDel()) {
                throw new HhException("收货地址有误");
            }
            if(!userInfoVo.getUid().equals(userAddress.getUid())){
                throw new HhException("收货地址异常，请重新选择");
            }
            request.setRealName(userAddress.getRealName());
            request.setPhone(userAddress.getPhone());
            userAddressStr = userAddress.getProvince() + userAddress.getCity() + userAddress.getDistrict() + userAddress.getDetail();
        }

        // 计算订单各种价格
        OrderComputedPriceRequest orderComputedPriceRequest = new OrderComputedPriceRequest();
        orderComputedPriceRequest.setShippingType(request.getShippingType());
        orderComputedPriceRequest.setAddressId(request.getAddressId());
        orderComputedPriceRequest.setCouponId(request.getCouponId());
        orderComputedPriceRequest.setUseIntegral(request.getUseIntegral());
        ComputedOrderPriceResponse computedOrderPriceResponse = computedPrice(orderInfoVo, userInfoVo);

        // 生成订单号
        String orderNo = HhUtil.getOrderNo();

        // 购买赠送的积分
        int gainIntegral = 0;
        List<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
        for (OrderInfoDetailVo detailVo : orderInfoVo.getOrderDetailList()) {
            // 赠送积分
            if (ObjectUtil.isNotNull(detailVo.getGiveIntegral()) && detailVo.getGiveIntegral() > 0) {
                gainIntegral += detailVo.getGiveIntegral() * detailVo.getPayNum();
            }
            // 订单详情
            StoreOrderInfo soInfo = new StoreOrderInfo();
            soInfo.setProductId(detailVo.getProductId());
            soInfo.setInfo(JSON.toJSON(detailVo).toString());
            soInfo.setUnique(detailVo.getAttrValueId().toString());
            soInfo.setOrderNo(orderNo);
            soInfo.setProductName(detailVo.getProductName());
            soInfo.setAttrValueId(detailVo.getAttrValueId());
            soInfo.setImage(detailVo.getImage());
            soInfo.setSku(detailVo.getSku());
            soInfo.setPrice(detailVo.getPrice());
            soInfo.setPayNum(detailVo.getPayNum());
            soInfo.setWeight(detailVo.getWeight());
            soInfo.setVolume(detailVo.getVolume());
            if (ObjectUtil.isNotNull(detailVo.getGiveIntegral()) && detailVo.getGiveIntegral() > 0) {
                soInfo.setGiveIntegral(detailVo.getGiveIntegral());
            } else {
                soInfo.setGiveIntegral(0);
            }
            soInfo.setIsReply(false);
            soInfo.setIsSub(detailVo.getIsSub());
            soInfo.setProductType(detailVo.getProductType());
            if (ObjectUtil.isNotNull(detailVo.getVipPrice())) {
                soInfo.setVipPrice(detailVo.getVipPrice());
            } else {
                soInfo.setVipPrice(detailVo.getPrice());
            }

            storeOrderInfos.add(soInfo);
        }

        // 下单赠送积分
        if (computedOrderPriceResponse.getPayFee().compareTo(BigDecimal.ZERO) > 0) {
            // 赠送积分比例
            String integralStr = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_KEY_INTEGRAL_RATE_ORDER_GIVE,isMer,merId);
            if (StrUtil.isNotBlank(integralStr)) {
                BigDecimal integralBig = new BigDecimal(integralStr);
                int integral = integralBig.multiply(computedOrderPriceResponse.getPayFee()).setScale(0, BigDecimal.ROUND_DOWN).intValue();
                if (integral > 0) {
                    // 添加积分
                    gainIntegral += integral;
                }
            }
        }

        // 支付渠道 默认：余额支付
        int isChannel = 3;
        if (request.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) {
            switch (request.getPayChannel()) {
                case PayConstants.PAY_CHANNEL_WE_CHAT_H5:// H5
                    isChannel = 2;
                    break;
                case PayConstants.PAY_CHANNEL_WE_CHAT_PUBLIC:// 公众号
                    isChannel = 0;
                    break;
                case PayConstants.PAY_CHANNEL_WE_CHAT_PROGRAM:// 小程序
                    isChannel = 1;
                    break;
                case PayConstants.PAY_CHANNEL_WE_CHAT_APP_IOS:// app ios
                    isChannel = 4;
                    break;
                case PayConstants.PAY_CHANNEL_WE_CHAT_APP_ANDROID:// app android
                    isChannel = 5;
                    break;
            }
        }
        if (request.getPayType().equals(PayConstants.PAY_TYPE_ALI_PAY)) {
            isChannel = 6;
            if (request.getPayChannel().equals(PayConstants.PAY_CHANNEL_ALI_APP_PAY)) {
                isChannel = 7;
            }
        }

        StoreOrder storeOrder = new StoreOrder();
        storeOrder.setUid(userInfoVo.getUid());
        storeOrder.setOrderId(orderNo);
        storeOrder.setRealName(request.getRealName());
        storeOrder.setUserPhone(request.getPhone());
        storeOrder.setUserAddress(userAddressStr);
        // 如果是自提
        if (request.getShippingType() == 2) {
            storeOrder.setVerifyCode(verifyCode);
            storeOrder.setStoreId(request.getStoreId());
        }
        storeOrder.setTotalNum(orderInfoVo.getOrderProNum());
        storeOrder.setCouponId(Optional.ofNullable(request.getCouponId()).orElse(0));

        // 订单总价
        BigDecimal totalPrice = computedOrderPriceResponse.getProTotalFee().add(computedOrderPriceResponse.getFreightFee());

        storeOrder.setTotalPrice(totalPrice);
        storeOrder.setProTotalPrice(computedOrderPriceResponse.getProTotalFee());
        storeOrder.setTotalPostage(computedOrderPriceResponse.getFreightFee());
        storeOrder.setCouponPrice(computedOrderPriceResponse.getCouponFee());
        storeOrder.setPayPrice(computedOrderPriceResponse.getPayFee());
        storeOrder.setPayPostage(computedOrderPriceResponse.getFreightFee());
        storeOrder.setDeductionPrice(computedOrderPriceResponse.getDeductionPrice());
        storeOrder.setPayType(request.getPayType());
        storeOrder.setUseIntegral(computedOrderPriceResponse.getUsedIntegral());
        storeOrder.setGainIntegral(gainIntegral);
        storeOrder.setMark(StringEscapeUtils.escapeHtml4(request.getMark()));
        storeOrder.setCombinationId(orderInfoVo.getCombinationId());
        storeOrder.setPinkId(orderInfoVo.getPinkId());
        storeOrder.setSeckillId(orderInfoVo.getSeckillId());
        storeOrder.setBargainId(orderInfoVo.getBargainId());
        storeOrder.setBargainUserId(orderInfoVo.getBargainUserId());
        storeOrder.setCreateTime(DateUtil.nowDateTime());
        storeOrder.setShippingType(request.getShippingType());
        storeOrder.setIsChannel(isChannel);
        storeOrder.setPaid(false);
        storeOrder.setCost(BigDecimal.ZERO);
        storeOrder.setType(0);
        storeOrder.setKeywords(orderInfoVo.getOrderDetailList().get(0).getProductName());
        storeOrder.setMerId(userInfoVo.getMerId());
        if (orderInfoVo.getIsVideo()) {
            storeOrder.setType(1);// 视频号订单
        }


        Boolean execute = transactionTemplate.execute(e -> {
            // 扣减库存

            for (MyRecord skuRecord : skuRecordList) {
                // 普通商品口库存
                storeProductService.operationStock(skuRecord.getInt("productId"), skuRecord.getInt("num"), "sub");
                // 普通商品规格扣库存
                attrValueService.operationStock(skuRecord.getInt("attrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_NORMAL);
            }


            newOrderService.create(storeOrder);
            storeOrderInfos.forEach(info -> info.setOrderId(storeOrder.getId()));

            // 保存购物车商品详情
            storeOrderInfoService.saveOrderInfos(storeOrderInfos);
            // 生成订单日志
            storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_STATUS_CACHE_CREATE_ORDER, "订单生成");

            // 清除购物车数据
            if (CollUtil.isNotEmpty(orderInfoVo.getCartIdList())) {
                storeCartService.deleteCartByIds(orderInfoVo.getCartIdList());
            }
            return Boolean.TRUE;
        });
        if (!execute) {
            throw new HhException("订单生成失败");
        }

        // 删除缓存订单
        if (redisUtil.exists(key)) {
            redisUtil.delete(key);
        }

        //投递订单支付延时消息
        int configTll = Integer.parseInt(this.systemConfigService.getValueByKey("order_cancel_time",isMer,merId));
        int exConfigTll = configTll * 60 * 1000 - 5000;
        this.rabbitTemplate.convertAndSend(RabbitMqConfig.DELAYED_MESSAGE_EXCHANGE,
                RabbitMqConfig.ORDER_DELAYED_CANCEL_QUEUE, orderNo, msg -> {
                    //设置延时
                    msg.getMessageProperties().setDelay(exConfigTll);
                    return msg;
                });

        MyRecord record = new MyRecord();
        record.set("orderNo", storeOrder.getOrderId());
        return record;
    }

    /**
     * 创建订单
     * @param storeOrder 订单参数
     * @return 结果标识
     */
    @Override
    public boolean create(StoreOrder storeOrder) {
        return dao.insert(storeOrder) > 0;
    }

    @Override
    public CommonPage<NewOrderDetailResponse> list(Integer status, String keywords,PageParamRequest pageRequest) {
        Integer userId = userService.getUserIdException();

        List<StoreOrder> orderList = newOrderService.getUserOrderList(userId, status,keywords, pageRequest);
        CommonPage<StoreOrder> storeOrderCommonPage = CommonPage.restPage(orderList);
        List<NewOrderDetailResponse> responseList = CollUtil.newArrayList();
        for (StoreOrder storeOrder : orderList) {
            NewOrderDetailResponse infoResponse = new NewOrderDetailResponse();
            BeanUtils.copyProperties(storeOrder, infoResponse);
            // 订单状态
            infoResponse.setOrderStatus(getH5OrderStatus(storeOrder));
            // 订单详情对象列表
            List<StoreOrderInfo> orderInfoList = storeOrderInfoService.getListByOrderNo(storeOrder.getOrderId());
            List<OrderInfoResponse> infoResponseList = CollUtil.newArrayList();
            orderInfoList.forEach(e -> {
                OrderInfoResponse orderInfoResponse = new OrderInfoResponse();
                orderInfoResponse.setStoreName(e.getProductName());
                orderInfoResponse.setImage(e.getImage());
                orderInfoResponse.setCartNum(e.getPayNum());
                orderInfoResponse.setPrice(ObjectUtil.isNotNull(e.getVipPrice()) ? e.getVipPrice() : e.getPrice());
                orderInfoResponse.setProductId(e.getProductId());
                orderInfoResponse.setSku(e.getSku());
                infoResponseList.add(orderInfoResponse);
            });
            infoResponse.setOrderInfoList(infoResponseList);
            responseList.add(infoResponse);
        }
        CommonPage<NewOrderDetailResponse> detailPage = CommonPage.restPage(responseList);
        BeanUtils.copyProperties(storeOrderCommonPage, detailPage, "list");
        return detailPage;
    }

    /**
     * 获取订单活动类型
     * @param storeOrder 订单都西昂
     * @return 活动类型
     */
    private String getOrderActivityType(StoreOrder storeOrder) {
        if (storeOrder.getSeckillId() > 0) {
            return "秒杀";
        }
        if (storeOrder.getCombinationId() > 0) {
            return "拼团";
        }
        if (storeOrder.getBargainId() > 0) {
            return "砍价";
        }
        if (storeOrder.getType().equals(1)) {
            return "视频号";
        }
        if (storeOrder.getShippingType().equals(2)) {
            return "核销";
        }
        return "普通";
    }

    /**
     * 获取H5订单状态
     * @param storeOrder 订单对象
     */
    private String getH5OrderStatus(StoreOrder storeOrder) {
        if (!storeOrder.getPaid()) {
            return "待支付";
        }
        if (storeOrder.getRefundStatus().equals(1)) {
            return "申请退款中";
        }
        if (storeOrder.getRefundStatus().equals(2)) {
            return "已退款";
        }
        if (storeOrder.getRefundStatus().equals(3)) {
            return "退款中";
        }
        if (storeOrder.getStatus().equals(-10)) {
            return "已取消";
        }
        if (storeOrder.getStatus().equals(0)) {
            return "待发货";
        }
        if (storeOrder.getStatus().equals(1)) {
            return "待收货";
        }
        if (storeOrder.getStatus().equals(2)) {
            return "待评价";
        }
        if (storeOrder.getStatus().equals(3)) {
            return "已完成";
        }
        return "";
    }

    /**
     * H5订单列表
     * @param uid 用户uid
     * @param status 评价等级|0=未支付,1=待发货,2=待收货,3=待评价,4=已完成,-3=售后/退款
     * @param pageParamRequest 分页参数
     * @return 订单结果列表
     */
    @Override
    public List<StoreOrder> getUserOrderList(Integer uid, Integer status, String keywords,PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        orderUtils.statusApiByWhere(lqw, status);
        lqw.eq(StoreOrder::getUid, uid);
        if(StrUtil.isNotBlank(keywords)){
            lqw.and(c->c.like(StoreOrder::getOrderId,keywords).or().like(StoreOrder::getKeywords,keywords));
        }
        lqw.orderByDesc(StoreOrder::getId);
        return dao.selectList(lqw);
    }

    @Override
    public NewStoreOrderDetailInfoResponse detailOrder(String orderId) {

        UserInfoVo userInfoVo = userService.getSimpleInfoException();

        NewStoreOrderDetailInfoResponse storeOrderDetailResponse = new NewStoreOrderDetailInfoResponse();
        // 查询订单
        StoreOrder storeOrder = newOrderService.getByOderId(orderId);
        if (ObjectUtil.isNull(storeOrder)) {
            throw new HhException("订单不存在");
        }
        if (!storeOrder.getUid().equals(userInfoVo.getUid())) {
            throw new HhException("订单不存在");
        }

        String merId = userInfoVo.getMerId();

        boolean isMer = MerUtils.isMer(merId);


        BeanUtils.copyProperties(storeOrder, storeOrderDetailResponse);
        MyRecord orderStatusVo = getOrderStatusVo(storeOrder,isMer,merId);
        // 订单详情对象列表
        List<OrderInfoResponse> infoResponseList = CollUtil.newArrayList();
        List<StoreOrderInfo> infoList = storeOrderInfoService.getListByOrderNo(storeOrder.getOrderId());
        infoList.forEach(e -> {
            OrderInfoResponse orderInfoResponse = new OrderInfoResponse();
            orderInfoResponse.setStoreName(e.getProductName());
            orderInfoResponse.setImage(e.getImage());
            orderInfoResponse.setCartNum(e.getPayNum());
            orderInfoResponse.setPrice(ObjectUtil.isNotNull(e.getVipPrice()) ? e.getVipPrice() : e.getPrice());
            orderInfoResponse.setProductId(e.getProductId());
            orderInfoResponse.setIsReply(e.getIsReply() ? 1 : 0);
            orderInfoResponse.setAttrId(e.getAttrValueId());
            orderInfoResponse.setSku(e.getSku());
            infoResponseList.add(orderInfoResponse);
        });
        storeOrderDetailResponse.setOrderInfoList(infoResponseList);
        //BeanUtils.copyProperties(storeOrder, storeOrderDetailResponse);
        storeOrderDetailResponse.setOrderStatus(orderStatusVo.getStr("title"));
        storeOrderDetailResponse.setOrderStatusMsg(orderStatusVo.getStr("msg"));
        storeOrderDetailResponse.setPayTypeStr(orderStatusVo.getStr("payTypeStr"));
        BigDecimal proTotalPrice = storeOrderDetailResponse.getPayPrice().add(storeOrderDetailResponse.getCouponPrice()).add(storeOrderDetailResponse.getDeductionPrice()).subtract(storeOrderDetailResponse.getPayPostage());
        storeOrderDetailResponse.setProTotalPrice(proTotalPrice);
        return storeOrderDetailResponse;
    }

    @Override
    public Boolean cancel(String orderId) {

        Integer userId = userService.getUserIdException();
        StoreOrder storeOrder = dao.getOrderItemUserByOrderId(orderId);
        if(!userId.equals(storeOrder.getUid())){
            throw new HhException("订单异常");
        }
        return newOrderService.doCancel(storeOrder,"用户取消未支付订单");
    }

    @Override
    public Boolean doCancel(StoreOrder storeOrder,String cancelMsg) {
        int i = dao.cancelOrder(storeOrder.getOrderId());
        if(i > 0){
            //恢复库存
            List<StoreOrderInfo> orderInfos = this.storeOrderInfoDao.getOrderInfoList(storeOrder.getId());

            for (StoreOrderInfo storeOrderInfo : orderInfos) {
                this.storeProductDao.addInventory(storeOrderInfo.getProductId(), storeOrderInfo.getPayNum());
                this.storeProductAttrValueDao.addInventory(storeOrderInfo.getAttrValueId(), storeOrderInfo.getPayNum());
            }
            //写订单日志 到期未支付系统自动取消
            this.storeOrderStatusService.createLog(storeOrder.getId(), "cancel", cancelMsg);
            return true;
        }
        return false;
    }

    /**
     * 订单确认收货
     * @param orderId
     * @return
     */
    @Override
    public boolean take(String orderId) {
        StoreOrder storeOrder = getByOrderIdException(orderId);

        if (!storeOrder.getStatus().equals(Constants.ORDER_STATUS_INT_SPIKE)) {
            throw new HhException("订单状态错误");
        }
        //已收货,就算完成了
        storeOrder.setStatus(Constants.ORDER_STATUS_INT_BARGAIN);
        storeOrder.setReceivingTime(DateUtil.nowDateTime());
        int i = dao.updateById(storeOrder);

        if (i > 0) {
            //后续操作放入redis
            redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_USER, orderId);
        }
        return i > 0;
    }

    /**
     * 订单删除
     * @param orderId
     * @return
     */
    @Override
    public boolean del(String orderId) {
        UserInfoVo simpleInfoException = userService.getSimpleInfoException();
        int i = dao.delOrder(orderId,simpleInfoException.getUid());
        return i > 0;
    }

    @Override
    public String showRefundInfo(String orderId) {
        Map<String,String> order = dao.getRefundInfoByOrderId(orderId);
        if(order != null){
            return order.get("refund_reason_wap");
        }else {
            return "暂时查询不到";
        }

    }

    @Override
    public Boolean refundApply(OrderRefundApplyRequest request) {
        Integer userId = userService.getUserIdException();
        StoreOrder storeOrderPram = new StoreOrder();
        storeOrderPram.setOrderId(request.getOrderId());
        storeOrderPram.setIsDel(false);
        storeOrderPram.setPaid(true);
        StoreOrder existStoreOrder = newOrderService.getByEntityOne(storeOrderPram);
        if (null == existStoreOrder) {
            throw new HhException("支付订单不存在");
        }
        if (existStoreOrder.getRefundStatus() == 1) {
            throw new HhException("正在申请退款中");
        }

        if (existStoreOrder.getRefundStatus() == 2) {
            throw new HhException("订单已退款");
        }

        if (existStoreOrder.getRefundStatus() == 3) {
            throw new HhException("订单退款中");
        }

        if(!userId.equals(existStoreOrder.getUid())){
            throw new HhException("订单退异常，无法操作");
        }

        existStoreOrder.setRefundStatus(1);
        existStoreOrder.setRefundReasonTime(DateUtil.nowDateTime());
        existStoreOrder.setRefundReasonWap(request.getCause());
        existStoreOrder.setRefundPrice(BigDecimal.ZERO);

        Boolean execute = transactionTemplate.execute(e -> {
            dao.updateById(existStoreOrder);
            storeOrderStatusService.createLog(existStoreOrder.getId(), Constants.ORDER_LOG_REFUND_APPLY, "用户申请退款原因：" + request.getCause());
            return Boolean.TRUE;
        });
        if (!execute) {
            throw new HhException("申请退款失败");
        }
        return execute;
    }

    /**
     * 订单基本查询一条
     * @param storeOrder 参数
     * @return 查询结果
     */
    @Override
    public StoreOrder getByEntityOne(StoreOrder storeOrder) {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        lqw.setEntity(storeOrder);
        return dao.selectOne(lqw);
    }


    /**
     * 获取订单状态相关信息
     * @return MyRecord
     */
    private MyRecord getOrderStatusVo(StoreOrder storeOrder,boolean isMer,String merId) {
        MyRecord record = new MyRecord();
        if (!storeOrder.getPaid()) {
            if(storeOrder.getStatus() == -10){
                record.set("type", -4);
                record.set("title", "交易关闭");
                record.set("msg", "交易已经取消");
            }else {
                record.set("type", 0);
                record.set("title", "未支付");
                record.set("msg", "订单未支付");
                List<String> configKeys = new ArrayList<>();
                configKeys.add("order_cancel_time");
                configKeys.add("order_activity_time");
                configKeys.add("order_bargain_time");
                configKeys.add("order_seckill_time");
                configKeys.add("order_pink_time");
                List<String> configValues = systemConfigService.getValuesByKes(configKeys,isMer,merId);
                Date timeSpace;
                timeSpace = DateUtil.addSecond(storeOrder.getCreateTime(),Double.valueOf(configValues.get(0)).intValue() * 3600);
                record.set("msg", DateUtil.getSecondTimestamp(timeSpace));
            }

        } else if (storeOrder.getRefundStatus() == 1) {
            record.set("type", -1);
            record.set("title", "申请退款中");
            record.set("msg", "商家审核中,请耐心等待");
        } else if (storeOrder.getRefundStatus() == 2) {
            record.set("type", -2);
            record.set("title", "已退款");
            record.set("msg", "已为您退款,感谢您的支持");
        } else if (storeOrder.getRefundStatus() == 3) {
            record.set("type", -3);
            record.set("title", "退款中");
            record.set("msg", "正在为您退款,感谢您的支持");
        } else if (storeOrder.getStatus() == 0) {
            record.set("type", 1);
            record.set("title", "未发货");
            record.set("msg", "商家未发货,请耐心等待");
        } else if (storeOrder.getStatus() == 1) { // 待收货处理
            // 待收货
            StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
            storeOrderStatus.setOid(storeOrder.getId());
            storeOrderStatus.setChangeType(Constants.ORDER_LOG_EXPRESS);
            record.set("type", 2);
            record.set("title", "待收货");
            record.set("msg", "商家已发货,请耐心等待");

        }else if (storeOrder.getStatus() == 2) {
//            record.set("type", 3);
//            record.set("title", "待评价");
//            record.set("msg", "已收货,快去评价一下吧");
            record.set("type", 3);
            record.set("title", "交易完成");
            record.set("msg", "交易完成,感谢您的支持");
        }else if (storeOrder.getStatus() == 3) {
            record.set("type", 4);
            record.set("title", "交易完成");
            record.set("msg", "交易完成,感谢您的支持");
        }
        // 支付方式
        String orderPayTypeStr = orderUtils.getOrderPayTypeStr(storeOrder.getPayType());
        record.set("payTypeStr", orderPayTypeStr);
        if (StringUtils.isNotBlank(storeOrder.getDeliveryType())) {
            record.set("deliveryType", StringUtils.isNotBlank(storeOrder.getDeliveryType()) ? storeOrder.getDeliveryType():"其他方式");
        }
        return record;
    }

    /**
     * 价格计算
     * @param orderInfoVo
     * @param user
     * @return
     */
    private ComputedOrderPriceResponse computedPrice(OrderInfoVo orderInfoVo, UserInfoVo user) {
        // 计算各种价格
        ComputedOrderPriceResponse priceResponse = new ComputedOrderPriceResponse();

        // 计算运费
        getFreightFee(orderInfoVo);
        priceResponse.setFreightFee(orderInfoVo.getFreightFee());

        // 计算优惠券金额(目前没有优惠券)
        priceResponse.setCouponFee(BigDecimal.ZERO);

        // 积分部分(目前没有积分)
        priceResponse.setDeductionPrice(BigDecimal.ZERO);
        priceResponse.setSurplusIntegral(user.getIntegral());
        priceResponse.setUsedIntegral(0);

        //实际支付金额
        BigDecimal payPrice = orderInfoVo.getProTotalFee().add(priceResponse.getFreightFee()).subtract(priceResponse.getCouponFee()).subtract(priceResponse.getDeductionPrice());
        priceResponse.setPayFee(payPrice);
        priceResponse.setProTotalFee(orderInfoVo.getProTotalFee());
        return priceResponse;
    }

    /**
     * 校验商品库存（生成订单）
     * @param orderInfoVo 订单详情Vo
     * @return List<MyRecord>
     * skuRecord 扣减库存对象
     * ——activityId             活动商品id
     * ——activityAttrValueId    活动商品skuId
     * ——productId              普通（主）商品id
     * ——attrValueId            普通（主）商品skuId
     * ——num                    购买数量
     */
    private List<MyRecord> validateProductStock(OrderInfoVo orderInfoVo, UserInfoVo userInfoVo) {
        List<MyRecord> recordList = CollUtil.newArrayList();
        // 普通商品
        List<OrderInfoDetailVo> orderDetailList = orderInfoVo.getOrderDetailList();
        orderDetailList.forEach(e -> {
            // 查询商品信息
            StoreProduct storeProduct = storeProductService.getById(e.getProductId());
            if (ObjectUtil.isNull(storeProduct)) {
                throw new HhException("购买的商品信息不存在");
            }
            if (storeProduct.getIsDel()) {
                throw new HhException("购买的商品已删除");
            }
            if (!storeProduct.getIsShow()) {
                throw new HhException("购买的商品已下架");
            }
            if (storeProduct.getStock().equals(0) || e.getPayNum() > storeProduct.getStock()) {
                throw new HhException("购买的商品库存不足");
            }
            // 查询商品规格属性值信息
            StoreProductAttrValue attrValue = attrValueService.getByIdAndProductIdAndType(e.getAttrValueId(), e.getProductId(), Constants.PRODUCT_TYPE_NORMAL);
            if (ObjectUtil.isNull(attrValue)) {
                throw new HhException("购买的商品规格信息不存在");
            }
            if (attrValue.getStock() < e.getPayNum()) {
                throw new HhException("购买的商品库存不足");
            }
            MyRecord record = new MyRecord();
            record.set("productId", e.getProductId());
            record.set("num", e.getPayNum());
            record.set("attrValueId", e.getAttrValueId());
            recordList.add(record);
        });
        return recordList;
    }

    /**
     * 校验预下单商品信息
     * @param request 预下单请求参数
     * @return OrderInfoVo
     */
    private OrderInfoVo validatePreOrderRequest(NewPreOrderRequest request, User user) {
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        List<OrderInfoDetailVo> detailVoList = CollUtil.newArrayList();
        if (request.getPreOrderType().equals("shoppingCart")) {// 购物车购买
            detailVoList = validatePreOrderShopping(request, user);
            List<Long> cartIdList = request.getOrderDetails().stream().map(NewPreOrderDetailRequest::getShoppingCartId).distinct().collect(Collectors.toList());
            orderInfoVo.setCartIdList(cartIdList);
        }
        if (request.getPreOrderType().equals("buyNow")) {// 立即购买
            // 立即购买只会有一条详情
            NewPreOrderDetailRequest detailRequest = request.getOrderDetails().get(0);

            // 普通商品
            if (ObjectUtil.isNull(detailRequest.getProductId())) {
                throw new HhException("商品编号不能为空");
            }
            if (ObjectUtil.isNull(detailRequest.getAttrValueId())) {
                throw new HhException("商品规格属性值不能为空");
            }
            if (ObjectUtil.isNull(detailRequest.getProductNum()) || detailRequest.getProductNum() < 0) {
                throw new HhException("购买数量必须大于0");
            }
            // 查询商品信息
            StoreProduct storeProduct = storeProductService.getById(detailRequest.getProductId());
            if (ObjectUtil.isNull(storeProduct)) {
                throw new HhException("商品信息不存在，请刷新后重新选择");
            }
            if (storeProduct.getIsDel()) {
                throw new HhException("商品已删除，请刷新后重新选择");
            }
            if (!storeProduct.getIsShow()) {
                throw new HhException("商品已下架，请刷新后重新选择");
            }
            if (storeProduct.getStock() < detailRequest.getProductNum()) {
                throw new HhException("商品库存不足，请刷新后重新选择");
            }
            // 查询商品规格属性值信息
            StoreProductAttrValue attrValue = attrValueService.getByIdAndProductIdAndType(detailRequest.getAttrValueId(), detailRequest.getProductId(), Constants.PRODUCT_TYPE_NORMAL);
            if (ObjectUtil.isNull(attrValue)) {
                throw new HhException("商品规格信息不存在，请刷新后重新选择");
            }
            if (attrValue.getStock() < detailRequest.getProductNum()) {
                throw new HhException("商品规格库存不足，请刷新后重新选择");
            }
            if(!user.getMerId().equals(storeProduct.getMerId())){
                throw new HhException("商户信息异常，请联系平台");
            }
            OrderInfoDetailVo detailVo = new OrderInfoDetailVo();
            detailVo.setProductId(storeProduct.getId());
            detailVo.setProductName(storeProduct.getStoreName());
            detailVo.setAttrValueId(attrValue.getId());
            detailVo.setSku(attrValue.getSuk());
            detailVo.setPrice(attrValue.getPrice());
            detailVo.setPayNum(detailRequest.getProductNum());
            detailVo.setImage(StrUtil.isNotBlank(attrValue.getImage()) ? attrValue.getImage() : storeProduct.getImage());
            detailVo.setVolume(attrValue.getVolume());
            detailVo.setWeight(attrValue.getWeight());
            detailVo.setTempId(storeProduct.getTempId());
            detailVo.setIsSub(storeProduct.getIsSub());
            detailVo.setProductType(Constants.PRODUCT_TYPE_NORMAL);
            detailVo.setVipPrice(detailVo.getPrice());
            detailVo.setGiveIntegral(storeProduct.getGiveIntegral());
            detailVoList.add(detailVo);

        }
        if (request.getPreOrderType().equals("again")) {// 再次购买
            NewPreOrderDetailRequest detailRequest = request.getOrderDetails().get(0);
            detailVoList = validatePreOrderAgain(detailRequest, user);
        }
        orderInfoVo.setOrderDetailList(detailVoList);
        return orderInfoVo;
    }

    /**
     * 购物车预下单校验
     * @param request 请求参数
     * @param user 用户
     * @return List<OrderInfoDetailVo>
     */
    private List<OrderInfoDetailVo> validatePreOrderShopping(NewPreOrderRequest request, User user) {
        List<OrderInfoDetailVo> detailVoList = CollUtil.newArrayList();
        request.getOrderDetails().forEach(e -> {
            if (ObjectUtil.isNull(e.getShoppingCartId())) {
                throw new HhException("购物车编号不能为空");
            }
            StoreCart storeCart = storeCartService.getByIdAndUid(e.getShoppingCartId(), user.getUid());
            if (ObjectUtil.isNull(storeCart)) {
                throw new HhException("未找到对应的购物车信息");
            }
            // 查询商品信息
            StoreProduct storeProduct = storeProductService.getById(storeCart.getProductId());
            if (ObjectUtil.isNull(storeProduct)) {
                throw new HhException("商品信息不存在，请刷新后重新选择");
            }
            if (storeProduct.getIsDel()) {
                throw new HhException("商品已删除，请刷新后重新选择");
            }
            if (!storeProduct.getIsShow()) {
                throw new HhException("商品已下架，请刷新后重新选择");
            }
            if (storeProduct.getStock() < storeCart.getCartNum()) {
                throw new HhException("商品库存不足，请刷新后重新选择");
            }
            // 查询商品规格属性值信息
            StoreProductAttrValue attrValue = attrValueService.getByIdAndProductIdAndType(Integer.valueOf(storeCart.getProductAttrUnique()), storeCart.getProductId(), Constants.PRODUCT_TYPE_NORMAL);
            if (ObjectUtil.isNull(attrValue)) {
                throw new HhException("商品规格信息不存在，请刷新后重新选择");
            }
            if (attrValue.getStock() < storeCart.getCartNum()) {
                throw new HhException("商品规格库存不足，请刷新后重新选择");
            }
            if(!user.getMerId().equals(storeProduct.getMerId())){
                throw new HhException("商户信息异常，请联系平台");
            }
            OrderInfoDetailVo detailVo = new OrderInfoDetailVo();
            detailVo.setProductId(storeProduct.getId());
            detailVo.setProductName(storeProduct.getStoreName());
            detailVo.setAttrValueId(attrValue.getId());
            detailVo.setSku(attrValue.getSuk());
            detailVo.setPrice(attrValue.getPrice());
            detailVo.setPayNum(storeCart.getCartNum());
            detailVo.setImage(StrUtil.isNotBlank(attrValue.getImage()) ? attrValue.getImage() : storeProduct.getImage());
            detailVo.setVolume(attrValue.getVolume());
            detailVo.setWeight(attrValue.getWeight());
            detailVo.setTempId(storeProduct.getTempId());
            detailVo.setGiveIntegral(storeProduct.getGiveIntegral());
            detailVo.setIsSub(storeProduct.getIsSub());
            detailVo.setProductType(Constants.PRODUCT_TYPE_NORMAL);
            detailVo.setVipPrice(detailVo.getPrice());
            detailVoList.add(detailVo);
        });
        return detailVoList;
    }

    /**
     * 再次下单预下单校验
     * @param detailRequest 请求参数
     * @return List<OrderInfoDetailVo>
     */
    private List<OrderInfoDetailVo> validatePreOrderAgain(NewPreOrderDetailRequest detailRequest, User user) {
        List<OrderInfoDetailVo> detailVoList = CollUtil.newArrayList();
        if (StrUtil.isBlank(detailRequest.getOrderNo())) {
            throw new HhException("再次购买订单编号不能为空");
        }
        StoreOrder storeOrder = getByOrderIdException(detailRequest.getOrderNo());
        if (storeOrder.getRefundStatus() > 0 || storeOrder.getStatus() != 2) {
            throw new HhException("只有已完成状态订单才能再次购买");
        }
        if (storeOrder.getSeckillId() > 0 || storeOrder.getBargainId() > 0 || storeOrder.getCombinationId() > 0) {
            throw new HhException("活动商品订单不能再次购买");
        }
        if (storeOrder.getType().equals(1)) {
            throw new HhException("视频订单不能再次购买");
        }
        // 获取订单详情
        List<StoreOrderInfoVo> infoVoList = storeOrderInfoService.getVoListByOrderId(storeOrder.getId());
        if (CollUtil.isEmpty(infoVoList)) {
            throw new HhException("订单详情未找到");
        }
        infoVoList.forEach(e -> {
            OrderInfoDetailVo detailVo = e.getInfo();
            // 查询商品信息
            StoreProduct storeProduct = storeProductService.getById(detailVo.getProductId());
            if (ObjectUtil.isNull(storeProduct)) {
                throw new HhException("商品信息不存在，请刷新后重新选择");
            }
            if (storeProduct.getIsDel()) {
                throw new HhException("商品已删除，请刷新后重新选择");
            }
            if (!storeProduct.getIsShow()) {
                throw new HhException("商品已下架，请刷新后重新选择");
            }
            if (storeProduct.getStock() < detailVo.getPayNum()) {
                throw new HhException("商品库存不足，请刷新后重新选择");
            }
            // 查询商品规格属性值信息
            StoreProductAttrValue attrValue = attrValueService.getByIdAndProductIdAndType(detailVo.getAttrValueId(), detailVo.getProductId(), Constants.PRODUCT_TYPE_NORMAL);
            if (ObjectUtil.isNull(attrValue)) {
                throw new HhException("商品规格信息不存在，请刷新后重新选择");
            }
            if (attrValue.getStock() < detailVo.getPayNum()) {
                throw new HhException("商品规格库存不足，请刷新后重新选择");
            }
            OrderInfoDetailVo tempDetailVo = new OrderInfoDetailVo();
            tempDetailVo.setProductId(storeProduct.getId());
            tempDetailVo.setProductName(storeProduct.getStoreName());
            tempDetailVo.setAttrValueId(attrValue.getId());
            tempDetailVo.setSku(attrValue.getSuk());
            tempDetailVo.setPrice(attrValue.getPrice());
            tempDetailVo.setPayNum(detailVo.getPayNum());
            tempDetailVo.setImage(StrUtil.isNotBlank(attrValue.getImage()) ? attrValue.getImage() : storeProduct.getImage());
            tempDetailVo.setVolume(attrValue.getVolume());
            tempDetailVo.setWeight(attrValue.getWeight());
            tempDetailVo.setTempId(storeProduct.getTempId());
            tempDetailVo.setGiveIntegral(storeProduct.getGiveIntegral());
            tempDetailVo.setIsSub(storeProduct.getIsSub());
            tempDetailVo.setProductType(Constants.PRODUCT_TYPE_NORMAL);
            tempDetailVo.setVipPrice(attrValue.getPrice());
            detailVoList.add(tempDetailVo);
        });
        return detailVoList;
    }

    private StoreOrder getByOrderIdException(String orderId) {
        StoreOrder storeOrder = newOrderService.getByOderId(orderId);
        if (ObjectUtil.isNull(storeOrder)) {
            throw new HhException("订单不存在");
        }
        if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            throw new HhException("订单不存在");
        }
        return storeOrder;
    }

    /**
     * 计算订单运费
     */
    private void getFreightFee(OrderInfoVo orderInfoVo) {
        //目前免运费
        orderInfoVo.setFreightFee(new BigDecimal("0"));
    }
}
